Support unsafe extern blocks#137
Closed
l2dy wants to merge 10 commits into
Closed
Conversation
Add grammar support for Rust 1.82's unsafe extern blocks feature (RFC 3484):
- Add 'safe' keyword to lexer
- Add SAFE token to parser
- Update Function rule to support 'safe?' modifier
- Update Constant rule to support '(safe | unsafe)?' qualifiers
This enables parsing of:
- unsafe extern "C" { ... } blocks
- safe fn function_name() in extern blocks
- unsafe fn function_name() in extern blocks
- safe/unsafe static items in extern blocks
Semantic validation (preventing both safe and unsafe on same item) will
be added in Phase 4 following the plugin's established pattern of
permissive parsing with semantic-level error checking.
Part of unsafe extern blocks migration (Phase 1 of 7).
Related to RFC 3484.
- Bump stub version from 234 to 235 - Add isUnsafe field to RsForeignModStub with serialization - Add SAFE_MASK to RsFunctionStub for safe keyword tracking - Add IS_SAFE_MASK and IS_UNSAFE_MASK to RsConstantStub - Add PSI extensions: RsForeignModItem.isUnsafe, RsFunction.isSafe, RsConstant.isSafe/isUnsafe Part of RFC 3484 unsafe extern blocks implementation.
- Add parser test fixture unsafe_extern_blocks.rs covering RFC 3484 syntax - Add test method for unsafe extern blocks in RsCompleteParsingTestCase - Update extern_block.rs comments to reflect edition 2024 validity - Regenerate extern_block.txt with updated PSI structure - Add RsForeignModStubTest for isUnsafe flag on extern blocks - Add RsForeignItemTest for safe/unsafe qualifiers on foreign items Parser tests: 4/4 passing Stub tests: 10/11 passing (1 requires Phase 4 semantic analysis) Part of RFC 3484 unsafe extern blocks implementation.
… (Phase 4) Updates isActuallyUnsafe to respect safe keyword in extern blocks: - Safe foreign functions can be called without unsafe blocks - Safe foreign statics can be accessed without unsafe blocks - Explicit unsafe modifier always makes items unsafe - Default (unmarked) items remain unsafe - Preserves wasm_bindgen and intrinsics special cases Changes: - RsFunction.isActuallyUnsafe: Check isSafe first, return false for safe items - RsUnsafeExpressionAnnotator: Skip safe foreign statics Tests: - Add RsForeignFunctionSafetyTest (6 tests for semantic analysis) - Add 6 annotator tests for safe/unsafe foreign items - All tests passing (64/64 across 3 test files) Part of RFC 3484 unsafe extern blocks implementation.
Implement Edition 2024 validation requiring unsafe keyword on extern blocks and prevent safe mutable statics in foreign modules. - Add requiresUnsafeKeyword property to detect Edition 2024+ - Add checkMissingUnsafeOnExternBlock in RsErrorAnnotator - Add checkSafeMutableStatic validation for foreign statics - Create AddUnsafeToExternBlockFix quick fix - Add error messages to RsBundle.properties - Add edition-based tests (10 tests, all passing)
Implements Phase 6 of the unsafe extern blocks migration plan, adding: - Keyword completion for safe/unsafe in extern blocks - Added SAFE to RS_KEYWORDS token set for proper formatter spacing This phase adds developer-facing IDE features that improve the experience of working with safe/unsafe foreign functions in Edition 2024 code.
Phase 1 implementation incorrectly added 'safe' as a hard keyword in the lexer, which broke parsing of standard library code that uses 'safe' as a variable name (e.g., `Ok(safe) => Some(safe)` in intrinsic.rs). This commit fixes the implementation by making 'safe' a contextual keyword following the established pattern for async, dyn, union, etc: - Remove 'safe' from RustLexer.flex (no hard keyword in lexer) - Change SAFE token to 'safe_kw' in RustParser.bnf (contextual keyword) - Add safeKeyword() parser utility that remaps IDENTIFIER to SAFE in context - Add SAFE to RS_CONTEXTUAL_KEYWORDS token set - Update PSI extensions to detect SAFE via node.findChildByType() Now 'safe' works as a keyword in extern blocks while remaining usable as a regular identifier everywhere else. Standard library parsing test now passes. Note: The parser allows safe/unsafe qualifiers on functions and statics at the grammar level (for better error recovery), but these qualifiers are semantically only valid within extern blocks. This is not currently enforced. Fixes parsing regression introduced in Phase 1 (commit 6a5cff3).
4e9621f to
31cbfec
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
For testing and posterity. Do not merge.
TODOs:
typeas an extern block item.